using System;
using System.Collections;
using System.Collections.Generic;
using System.Html;
using System.Runtime.CompilerServices;
using Awaiter;
using Nsb;
using Nsb.Classes;
using Yoshi.Classes;
using jQueryApi;

namespace ThemeChain
{
    [IgnoreNamespace]
    public class ThemeYoshi : ThemeBase
    {
        private const int Trans = 250;
        public const int SlideDown = Trans;
        public const int SlideUp = Trans;
        public const int FadeIn = Trans;
        public const int FadeOut = Trans - 100;
        public const int ZIndexHider = 999;

        public const string OkBtnFace = "Oh Yea!";
        public const string Says = "<i>says</i>";
        public const string ForSure = "Remove for sure?";
        public const string UnGroupClusterMsg = "This group is a cluster and cannot be ungrouped.";
        public const string CancelBtnFace = "Not really";
        public const string AlivenessAddBtnFace = "&hearts; Add to my aliveness stream!";
        public const string AlivenessEditBtnFace = Hearts + " Save aliveness changes <b>" + Smile + "</b>";
        public const string CommentAddBtnFace = "&clubs; Add this comment";
        public const string LikeBtnTitle = "I like this aliveness thought!";
        public const string CommentBtnTitle = "Click to add a comment";
        public const string EditBtnTitle = "Click to edit this item";
        public const string StreamBtnTitle = "Click to add this to your aliveness stream";
        public const string DeleteBtnTitle = "Delete";
        public const string AddNewItemBtnTitle = "Add a new item";
        public static string UnknownUserPhoto = Uri.Img("Photos/Person.jpg");
        private static readonly bool ThemeYoshiInitialized = Helpers.StaticInheritClass(typeof(ThemeYoshi).Name, typeof(ThemeBase).Name);

        public static PagesD Pages;

        public static readonly Dictionary DefaultPageCss = new Dictionary(
            "background", "center bottom no-repeat",
            "background-image", "none",
            "background-color", "#000",
            "min-height", "500px",
            "color", "#DDD"
            );

        static ThemeYoshi()
        {
            jQuery.Ajax(
                (jQueryAjaxOptions)(object)new Dictionary(
                    "type", "HEAD",
                    "url", Uri.App("@MasterVersion.txt"),
                    "cache", false,
                    "success",
                    (Action<object, string, jQueryXmlHttpRequest>)
                    delegate(object o, string s, jQueryXmlHttpRequest xr)
                    {
                        string modified = xr.GetResponseHeader("Last-Modified");
                        if (!String.IsNullOrEmpty(modified))
                        {
                            int modtime = new Date(modified).GetTime();
                            int delta = modtime - (int)Script.Literal("window.ScriptVersion");
                            Inform.Debug("Script modified delta = {0}", delta);
                            if (delta > 0)
                            {
                                Inform.Error("Software out of date. delta={0}", delta);
                                //new Await()
                                //    .AddAw(new Ask().OkAw, "Software has been enhanced, reloading page.")
                                //    .AddFn(RebuildPackageEv)
                                //    .Commit();
                            }
                        }
                    },
                    "error", (Action)delegate {}
            ));
        }

        public static bool EscapeOut;
        public static bool SupressCurateEvents;

        public static string LogoImage = Uri.Img("Common/LOGO1.JPG");
        public static string SiteTitle = "<span style='color: #3289CE'>Play</span> <span style='color: #000'>Nexus</span><span style='font-family:comic sans ms'>&trade;</span>";

        public static string DefaultPageClass = "VirtualPage";
        public static string PageAttrKey = "PageClass";
        public static string PageNameKey = "PageName";
        public static string DefaultPageName = "home";
        public static string AdminPageName = "admin";
        public static string CuratorId = "curator";
        public static string ImagesPartitionKey = "pg/images";
        public static string ImagesRowKey = "@images";

        public static string CurrentPageClass;
        public static string CurrentPageName;
        public static string BgImgUrl;
        public static string PagesDataPath;
        public static string PagesPartition = "pg/gigs";
        public static string PagesRowKey = "Pages";
        public static Action<string, string> GoPage;
        public static string MasterPage = "master.html";
        public static string MasterScripts = "master.php";
        public static string CurrentBuildAction;
        public static string CurrentLoadCss;
        public static string CurrentLoadLibs;
        public static string PublishingKey = "Publishing";
        public static string Email = "";
        public static string UserId = "";
        public static bool PageDone;
        public static bool SupportsAudio = (bool)Script.Literal("!!document.createElement('audio').canPlayType");

        public static string UnknownUrlEv = "BadUrl";

        public static string MetaBarKey
        {
            get { return KeyPrefix + "/MetaBar"; }
        }

        public static string CuratingKey
        {
            get { return KeyPrefix + "/Curating"; }
        }

        public static string CuratePasswordKey
        {
            // Must be dynamic since purely static may not have initialized before use due to loading orders
            get { return KeyPrefix + "/CuratePassword"; }
        }

        public static readonly Dictionary TestUsers =
            new Dictionary(
                "100002776766039", true,
                "TestUser1", true,
                "TestUser2", true,
                "TestUser3", true
                );

        public static void ReloadPage()
        {
            Reloading = true;
            if (!String.IsNullOrEmpty(Uri.Query(Window.Location.Href)))
                Window.Location.Href = Uri.Path(Window.Location.Href);
            else
                Window.Location.Reload(true);
        }

        [AlternateSignature]
        public static extern void RebuildPackageEv();

        public static void RebuildPackageEv(jQueryEvent e)
        {
            DomElement.CancelEvent(e);
            Storage.SetLocal(PublishingKey, false);
            new Await()
                .AddAw(RebuildPackageAw)
                .AddDx(delegate { ReloadPage(); })
                .Commit();
        }

        public static void RebuildPackageAw(Await awp)
        {
            string url = Uri.Scripts(MasterScripts + "?minimize=y");
            string pw = (string)Storage.GetLocal(DevPasswordKey);
            if (pw != null)
            {
                url = Uri.AddPair(url, "debug", "y");
                url = Uri.AddPair(url, "password", pw);
            }
            Cluster.Spinner(true);
            Uri.BumpVersion();
            new Await()
                .LoadScript(Uri.Versionize(url))
                .Commit(awp);
        }

        public static void ToPublished(jQueryEvent e)
        {
            DomElement.CancelEvent(e);
            Storage.SetLocal(CuratingKey, false);
            Window.Location.Href = PublishedUrl();
        }

        public static void ToPublishedHome(jQueryEvent e)
        {
            DomElement.CancelEvent(e);
            Storage.SetLocal(CuratingKey, false);
            Window.Location.Href = Uri.Join("pages", DefaultPageName + ".html");
        }

        public static string BaseUrl()
        {
            return Uri.Front(Window.Location.Href) + "/";
        }

        public static string PublishedUrl()
        {
            return Uri.Join("pages", CurrentPageName + ".html");
        }

        public static PageD CurrentPage
        {
            get { return Pages.pages[CurrentPageName]; }
        }

        public static bool IsAdmin
        {
            get
            {
                try
                {
                    return CurrentPage.Admin;
                }
                catch
                {
                    return true;
                }
            }
        }

        [PreserveName, PreserveCase]
        public static bool IsCurateUrl(string url)
        {
            return url.IndexOf(MasterPage) == 0;
        }

        public static string LocalUrl(string url)
        {
            if (!((RegularExpression)Script.Literal(@"/^https?:\/\//")).Test(url))
                return url;
            if (url.IndexOf(BaseUrl()) == 0)
                return url.Substr(BaseUrl().Length);
            return null;
        }

        public static readonly RegularExpression SafePageRx = (RegularExpression)Script.Literal(@"/^\.(html|htm|txt|gif|jpeg|jpg|png)$/");

        [PreserveName, PreserveCase]
        public static string SmartUrl(string url)
        {
            try
            {
                if (((RegularExpression)Script.Literal(@"/^www\./i")).Test(url))
                    return "http://" + url;
                if (((RegularExpression)Script.Literal(@"/^base:/")).Test(url))
                    return url.Substr(5).Trim();
                if (((RegularExpression)Script.Literal(@"/^https?:\/\//i")).Test(url))
                    return url;
                if (SafePageRx.Test(Uri.Ext(url)))
                    return url;
                string sn = Strings.SafeFileName(url);
                if (Pages.pages[sn] != null)
                    return Uri.AddPair(MasterPage, "page", sn);
            }
            catch
            {
            }
            jQuery.Document.Trigger(UnknownUrlEv, (object[])(object)url);
            return url;
        }

        [PreserveName, PreserveCase]
        public static string UnSmartUrl(string url)
        {
            try
            {
                if (IsCurateUrl(url))
                    return Pages.pages[Uri.GetValue(url, "page") ?? DefaultPageName].Face;
                if (((RegularExpression)Script.Literal(@"/^https?:\/\//i")).Test(url))
                    return url;
                if (SafePageRx.Test(Uri.Ext(url)))
                    return url;
                return url;
            }
            catch
            {
                return url;
            }
        }

#pragma warning disable 108,114
        public static string ParseEditToAnchors(string txt)
#pragma warning restore 108,114
        {
            return UriParse.ParseEditToAnchors(txt);
        }

#pragma warning disable 108,114
        public static string ParseAnchorsToEdit(string txt)
#pragma warning restore 108,114
        {
            return UriParse.ParseAnchorsToEdit(txt);
        }

        public static void SetDevRefresh()
        {
            Storage.SetLocal("DevRefresh", true);
        }

        public static bool ConsumeDevRefresh
        {
            get
            {
                bool ic = (bool)Storage.GetLocal("DevRefresh");
                Storage.SetLocal("DevRefresh", false);
                return ic;
            }
        }
    }
}

namespace Yoshi.Classes
{
    [IgnoreNamespace]
    public abstract class PagesD
    {
        public Dictionary<string, PageD> pages;
    }

    [IgnoreNamespace]
    public sealed class PageD
    {
        [PreserveCase]
        public bool Admin;
        [PreserveCase]
        public string Class;
        [PreserveCase]
        public string Face;
        [PreserveCase]
        public string Name;
        [PreserveCase]
        public string Tests;
        [PreserveCase]
        public string Title;
        [PreserveCase]
        public bool Visible;
    }
}